------------> Furb3T <-----------

presenta:

Capire un generatore di seriale: II parte.

   Salve giovani amanti dell'assembler, oggi andremo avanti con la lezione sui generatori di chiave e analizzeremo il codice di un programma che usiamo tutti o quasi: il MIRC 5.31. Utilizzeremo come al solito SOFTICE. Lanciamo Mirc, andiamo sotto HELP|REGISTER ed inseriamo il nome e il codice numerico. Ctrl-D e fissiamo un bel BPX MESSAGEBOXA, F5 per ritornare su Mirc, diamo l'OK e...BOOM eccoci su Softice, premiamo F12 e ci ritroviamo su Mirc che ci fa comparire la finestra di messaggio che ci dice che abbiamo sbagliato codice (...ancora per poco), premiamo OK e rieccoci dentro Softice, ed esattamente qui:

:00437E9C      push 00000010
:00437E9E   
  push 004B4EC2   
:00437EA3      push 004B4E2C
   
:00437EA8      mov eax, dword ptr [ebp+08]
:00437EAB     push eax
:00437EAC     Call USER32.MessageBoxA

:00437EB1       push 00000083          --------------> punto di atterraggio
:00437EB6      mov eax, dword ptr [ebp+08]

    Bene ora non vi resta che fare un p� di scroll up ovvero far scorrere verso l'alto per vedere quale � la parte di codice che chiama la MessageBox; scorrete scorrete ed arriverete qui:

:00437DE7        push 004C07CC     -----------> fate d 4C07CC leggerete il codice che avete scritto
:00437DEC       push 004C0510
       -----------> qui troverete il nome che avete scritto
:00437DF1        call 004822D0
        -----------> call che effettua il controllo della validit� e ritorna il valore
:00437DF6        add esp, 00000008
                        in EAX
:00437DF9        test eax, eax
:00437DFB        je 00437E67            
-----------> se EAX = 0 allora salta alla MessageBox di prima
:00437DFD       push 004B77A4
:00437E02         push 004B4DC0

    Avrete capito che bisogner� andare a spulciare nella CALL che sta all'indirizzo 00437DF1; facciamo un bel Trace della call:

:004822D0    push ebp
:004822D1     mov ebp, esp
:004822D3      push ebx
:004822D4      push esi
:004822D5      push edi
:004822D6      mov esi, dword ptr [ebp+0C]
:004822D9      mov ebx, dword ptr [ebp+08]
:004822DC     push ebx
           -------------> Scrivete d ebx comparir� il nome che avete inserito
:004822DD     call 004A4060
  ------------> calcola la lunghezza del nome inserito e la mette in EAX
:004822E2      pop ecx
:004822E3      cmp eax, 00000005
  ----> se la lunghezza del nome inserito � pi� piccola di 5, non salta    
:004822E6      jnb 004822EC
            ------> quindi il nome da inserire deve essere pi� lungo di 5
:004822E8      xor eax, eax
:004822EA     jmp 00482363
:004822EC     push esi
:004822ED     push ebx
:004822EE     call 004821F0
        -------> un'altra Call che fa un controllo su nome e codice
:004822F3      add esp, 00000008
:004822F6      test eax, eax
        -------> la Call ritorna EAX= 0 se non � giusto il codice altrimenti EAX=1
:004822F8      je 00482301
:004822FA     mov eax, 00000001
:004822FF     jmp 00482363

    Non siamo ancora arrivati al pezzo di codice che ci serve per capire come viene generato il vero codice; dobbiamo fare il Trace della CALL che sta a 004822EE, quindi:

.....................
:004821FC  push 0000002D
--------> 2D non � altro che il "-" (trattino), ci� vuol dire che il codice vero
:004821FE  push esi
                              da inserire deve contenere il trattino e che quindi sar� composto
:004821FF  call 004A400C
                   da 2 parti. Questa Call verifica l'esistenza del trattino e ritorna 0 in
:00482204  add esp, 00000008
         EAX se non c'�.
:00482207  mov ebx, eax
:00482209  test ebx, ebx
:0048220B  jne 00482214
....................
....................

00482254       add ecx, 00000003 --------> questa parte calcola la prima parte di codice. In ECX abbiamo
:00482257     cmp edx, dword ptr [ebp-0C]
            il nome che abbiamo inserito. Osservate come
:0048225A     jge 00482278
                                 aggiunga a ECX il valore 00000003
:0048225C     movzx esi, byte ptr [ecx]
    ------> muove in ESI i caratteri in Ascii esadecimale dal 3 in poi
:0048225F     imul esi, dword ptr [4*eax+004BBB44]
  -----> moltiplica ESI per il risultato della parentesi e
:00482267     add ebx, esi
                                                         mette il risultato in ESI, per poi sommarlo a EBX
:00482269     inc eax
       ---------> incrementa il valore di EAX che partiva da 0
:0048226A    cmp eax, 00000026
:0048226D    jle 00482271
:0048226F    xor eax, eax
:00482271    inc edx     
-----------> incrementa EDX 
:00482272    inc ecx
      -----------> incrementa ECX
:00482273    cmp edx, dword ptr [ebp-0C]
    -----------> ripete il loop finch� EDX non � uguale alla 
:00482276    jl 0048225C
                                                        lunghezza del nome che avete inserito.

    Ok, mi sembra abbastanza facile da capire come viene generata la prima parte del codice, l'unica cosa che vi risulter� difficile da capire � cosa avviene nel prodotto tra ESI e [.....]. Allora che vuol dire 4*eax+004BBB44? Ve lo spiego subito. Se scrivete d 004BBB44, vedrete nella finestra una cosa tipo questa:

0B 00 00 00 06 00 00 00 11 00 00 00 0C
0C 00 00 00 0E 00 00 00  05 00 00 00 0C
....................................................
    

Sapendo che Eax parte da 0, allora nel primo loop il ESI verr� moltiplicato per B, nel secondo loop Esi verr� moltiplicato per 6, nel terzo per 11, nel quarto per C e cos� via...Capito?!?!? Facile vero!!! Bene ora analizziamo l'altra parte di codice come viene costruita:

...........................
:0048228D  add ecx, 00000003    
---------> ancora una volta il nome viene preso dalla 3 lettera
:00482290   cmp edx, dword ptr [ebp-0C]
:00482293   jge 004822B8
:00482295   movzx esi, byte ptr [ecx]
----> muove in ESI i caratteri ASCii Esadec. del nome dal 3 in poi
:00482298   movzx edi, byte ptr [ecx-01]
---> muove in EDI i caratteri Ascii Esa del nome dal 2 in poi
:0048229C   imul esi, edi   
--------> moltiplica ESI per EDI e il mette il risultato in ESI
:0048229F   imul esi, dword ptr [4*eax+004BBB44]
-----> moltiplica ESI per il fattore tra le [.....]
:004822A7   add ebx, esi              
--------> somma ESI a EBX e mette il risultato in EBX
:004822A9   inc eax
:004822AA  cmp eax, 00000026
:004822AD  jle 004822B1
:004822AF   xor eax, eax
:004822B1   inc edx
          -----------> incrementa EDX
:004822B2   inc ecx            
----------> incrementa ECX
:004822B3   cmp edx, dword ptr [ebp-0C]
----> ripete il loop se EDX � minore della lunghezza del nome
:004822B6   jl 00482295

    Insomma, anche questa seconda parte del codice ora � svelata. Quando creerete il vostro bel programmino di keygen, ricordatevi bene tutti i percorsi dell'algoritmo di calcolo, nonch� del trattino..... inoltre ricordatevi di citarmi nel programma!!!!!

    Purtroppo io programmo in VB quindi non vi scriver� il programma keygen, questo toccher� a voi implementarlo con il linguaggio che sapete usare di pi�. A presto miei fidi!!!!

Ringraziamenti: a tutto il gruppo RingZer0 per il supporto Tecnico e Morale, ed a Insanity perch�                          pubblica i miei tutorial.